iT邦幫忙

2024 iThome 鐵人賽

DAY 26
0
自我挑戰組

30 天 Node.js 探索:基礎、進階與實踐系列 第 26

Day 26: 錯誤處理與日誌管理

  • 分享至 

  • xImage
  •  

在今天的內容中,會學習如何在個人財務管理應用中實施錯誤處理與日誌管理。良好的錯誤處理機制和日誌記錄對應用程式的穩定性與可維護性至關重要。這不僅能夠及時發現問題,還能為除錯與優化提供有效的資料支持。

錯誤處理的最佳實踐

在 Node.js 應用中,錯誤可以分為兩種主要類型:

  • 同步錯誤: 在程式執行期間直接拋出的錯誤。
  • 非同步錯誤: 通常發生在異步操作中,像是讀取文件或發送 HTTP 請求時。

同步錯誤處理

同步錯誤可以使用 try...catch 來捕捉。當發生錯誤時,catch 區塊會接收到錯誤並處理它。
範例:

js
try {
  // 一段可能出錯的代碼
  const data = JSON.parse('Invalid JSON String');
} catch (error) {
  console.error('JSON parsing error:', error.message);
}

非同步錯誤處理

Node.js 的非同步函數,如回調函數或 Promise,也需要特別的錯誤處理方式。對於使用 Promise 的非同步代碼,可以使用 .catch() 或 async/await 搭配 try...catch。
範例:

js
async function fetchData() {
  try {
    const response = await axios.get('https://api.example.com/data');
    return response.data;
  } catch (error) {
    console.error('Error fetching data:', error.message);
  }
}

全域錯誤處理

為了防止應用程式崩潰,可以設置全域的錯誤處理機制,捕捉未處理的異常和 Promise 拋出的錯誤。

捕捉未處理的異常

使用 process.on('uncaughtException') 可以捕捉應用中的未處理異常,避免程序意外中斷。
範例:

js
process.on('uncaughtException', (error) => {
  console.error('Uncaught exception:', error.message);
  process.exit(1); // 當發生重大錯誤時,最好讓程序重啟
});

捕捉未處理的 Promise 拋出錯誤

使用 process.on('unhandledRejection') 來捕捉未處理的 Promise 錯誤。
範例:

js
process.on('unhandledRejection', (reason, promise) => {
  console.error('Unhandled Rejection at:', promise, 'reason:', reason);
});

日誌管理

在 Node.js 應用中,良好的日誌管理可以幫助開發者追蹤應用程式的運行狀況。這裡介紹使用 winston 庫來進行日誌管理。

安裝 winston

bash
npm install winston

設置基本日誌記錄

winston 是一個強大的日誌管理工具,支援多種日誌等級和輸出方式(如文件、控制台等)。
範例:logger.js

js
const winston = require('winston');

const logger = winston.createLogger({
  level: 'info',
  format: winston.format.combine(
    winston.format.timestamp(),
    winston.format.json()
  ),
  transports: [
    new winston.transports.Console(), // 控制台日誌
    new winston.transports.File({ filename: 'logs/error.log', level: 'error' }), // 錯誤日誌
    new winston.transports.File({ filename: 'logs/combined.log' }) // 全部日誌
  ],
});

module.exports = logger;

在應用中使用日誌

可以將 logger 整合到各個路由和服務中來記錄應用程序的關鍵事件,例如錯誤、用戶行為、系統運行狀況等。
範例:

js
const logger = require('./logger');

app.use((err, req, res, next) => {
  logger.error(`${err.message} - ${req.originalUrl} - ${req.method} - ${req.ip}`);
  res.status(500).json({ msg: 'Server error' });
});

實作錯誤處理與日誌管理

新增 logs 資料夾

為了讓日誌可以正確儲存,需要在專案目錄下新增一個名為 logs 的資料夾,這裡將存放所有日誌文件。

bash
mkdir logs

新增 logger.js 文件

在專案目錄下新增一個 logger.js 文件,用於設定日誌管理功能。這個文件負責將 winston 設定並導出一個全局可用的日誌器。

js
const winston = require('winston');
const path = require('path');

// 設置日誌存放位置和格式
const logger = winston.createLogger({
  level: 'info',
  format: winston.format.combine(
    winston.format.timestamp(),
    winston.format.json()
  ),
  transports: [
    new winston.transports.Console(),
    new winston.transports.File({ filename: path.join(__dirname, 'logs', 'error.log'), level: 'error' }),
    new winston.transports.File({ filename: path.join(__dirname, 'logs', 'combined.log') })
  ],
});

module.exports = logger;

在主應用文件(sever.js)中引入 logger.js

接著,需要在主應用程式文件中引入 logger,並且將其應用在所有的請求和錯誤處理上。

js
const express = require('express');
const logger = require('./logger');  // 引入日誌功能
const app = express();

// 記錄所有請求
app.use((req, res, next) => {
  logger.info(`Request received: ${req.method} ${req.url}`);
  next();
});

// 處理路由或其他邏輯

// 捕捉錯誤,並記錄到日誌
app.use((err, req, res, next) => {
  logger.error(`Error occurred: ${err.message}`);
  res.status(500).json({ message: 'Internal Server Error' });
});

測試錯誤處理與日誌管理

  1. 模擬錯誤
  • 測試用戶請求錯誤的路由來模擬錯誤,查看是否正確記錄到 error.log 文件中。
  • 使用 Postman 模擬發送不正確的 API 請求。
  1. 查看日誌
  • 檢查 logs/combined.log 和 logs/error.log,確認應用程式運行期間的所有錯誤與請求是否正確記錄。

總結

今天深入探討了如何在 Node.js 應用中實作錯誤處理與日誌管理。錯誤處理幫助在異常情況下保護應用程式,避免崩潰。而日誌管理則提供了詳盡的應用運行記錄,幫助進行診斷與優化。在接下來的開發過程中,這些功能將大大提升我們應用的穩定性與可維護性。


上一篇
Day 25: 類別與標籤管理功能
系列文
30 天 Node.js 探索:基礎、進階與實踐26
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言